package com.atchangsha.system.service.impl;

import com.atchangsha.system.common.utils.Result;
import com.atchangsha.system.constant.FoodTableConstants;
import com.atchangsha.system.dao.FoodTableDao;
import com.atchangsha.system.dao.MenusOrderRelationDao;
import com.atchangsha.system.dao.OrderDao;
import com.atchangsha.system.dao.SalesBillDao;
import com.atchangsha.system.dto.CreateTableDTO;
import com.atchangsha.system.dto.FoodTableDTO;
import com.atchangsha.system.entity.MenusOrderRelationEntity;
import com.atchangsha.system.entity.OrderEntity;
import com.atchangsha.system.entity.SalesBillEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atchangsha.system.common.utils.PageUtils;
import com.atchangsha.system.common.utils.Query;
import com.atchangsha.system.entity.FoodTableEntity;
import com.atchangsha.system.service.FoodTableService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

@Service("foodTableService")
@Slf4j
public class FoodTableServiceImpl extends ServiceImpl<FoodTableDao, FoodTableEntity> implements FoodTableService {
    @Resource
    FoodTableService foodTableService;
    @Resource
    OrderDao orderDao;
    @Resource
    MenusOrderRelationDao menusOrderRelationDao;
    @Resource
    SalesBillDao salesBillDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Object key = params.get("key");
        QueryWrapper<FoodTableEntity> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(key)) {
            wrapper.like("chair_area", key).or().like("id", key);
        }
        IPage<FoodTableEntity> page = this.page(
                new Query<FoodTableEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    public Boolean createTable(CreateTableDTO createTableDTO) {
        //餐桌开台
        Long tableId = createTableDTO.getTableId();
        FoodTableEntity foodTableEntity = foodTableService.getById(tableId);
        // 餐桌正在使用
        if ("0".equals(foodTableEntity.getStatus())) {
            return false;
        }
        // 修改餐桌状态
        foodTableEntity.setCurrentNumber(createTableDTO.getNumber());
        foodTableEntity.setStatus("1");
        // 返回是否修改成功
        return foodTableService.updateById(foodTableEntity);
    }

    @Override
    public Result add(FoodTableDTO foodTableDTO) {
        FoodTableEntity foodTableEntity = foodTableDTO.toEntity();
        int insert = baseMapper.insert(foodTableEntity);
        if (insert == 1) {
            return Result.ok(FoodTableConstants.FoodTableEnum.ADD_SUCCESS).setResult(foodTableEntity.toVO());
        }
        log.error(FoodTableConstants.FoodTableEnum.ADD_FAIL.getMsg());
        return Result.fail(FoodTableConstants.FoodTableEnum.ADD_FAIL);
    }

    @Override
    public Result updateFoodTable(FoodTableDTO foodTableDTO) {
        FoodTableEntity foodTableEntity = foodTableDTO.toEntity();
        int length = baseMapper.updateById(foodTableEntity);
        if (length == 1) {
            return Result.ok(FoodTableConstants.FoodTableEnum.UPDATE_SUCCESS).setResult(foodTableEntity);
        }
        log.error(FoodTableConstants.FoodTableEnum.UPDATE_SUCCESS.getMsg());
        return Result.fail(FoodTableConstants.FoodTableEnum.UPDATE_SUCCESS);
    }

    @Override
    @Transactional
    public Result removeByIdArray(List<Long> asList) {
        //根据餐桌id集合删除所有餐桌信息
        int length = baseMapper.deleteBatchIds(asList);
        if (length != asList.size()) {
            //删除全部餐桌信息失败
            log.error(FoodTableConstants.FoodTableEnum.DELETE_FAIL.getMsg());
            return Result.fail(FoodTableConstants.FoodTableEnum.DELETE_FAIL);
        }
        //遍历餐桌id
        for (Long id : asList) {
            //根据餐桌id获取关于该餐桌id的所有订单信息
            List<OrderEntity> list = orderDao.selectList(new QueryWrapper<OrderEntity>().eq("food_table_id", id).and(Wrapper -> Wrapper.eq("remove_flag", 0).or().eq("remove_flag", 1)));
            //收集所有的订单id
            List<Long> collect = list.stream().map(item -> {
                return item.getId();
            }).collect(Collectors.toList());
            if (collect.size() != 0){
                //删除关于该餐桌的所有订单信息
                int num = orderDao.deleteBatchIds(collect);
                if (list.size() != num) {
                    log.error(FoodTableConstants.FoodTableEnum.DELETE_ORDER_FAIL.getMsg());
                    return Result.fail(FoodTableConstants.FoodTableEnum.DELETE_ORDER_FAIL);
                }

                //遍历所有的订单id
                for (Long orderId : collect) {
                    //查询出关于该订单id的所有菜单订单关系记录
                    List<MenusOrderRelationEntity> relationEntities = menusOrderRelationDao.selectList(new QueryWrapper<MenusOrderRelationEntity>().eq("order_id", orderId));
                    //收集所有菜单订单关系记录id
                    List<Long> longs = relationEntities.stream().map(item -> {
                        return item.getId();
                    }).collect(Collectors.toList());
                    //删除所有关于该订单id的菜单订单关系记录
                    int deleteBatchIds = menusOrderRelationDao.deleteBatchIds(longs);
                    if (deleteBatchIds != relationEntities.size()) {
                        log.error(FoodTableConstants.FoodTableEnum.DELETE_RELATION_FAIL.getMsg());
                        return Result.fail(FoodTableConstants.FoodTableEnum.DELETE_RELATION_FAIL);
                    }
                    //查询出关于该订单id的消费记录
                    SalesBillEntity salesBillEntity = salesBillDao.selectOne(new QueryWrapper<SalesBillEntity>().eq("order_id", orderId));
                    //删除关于该订单id的消费记录
                    int delete = salesBillDao.deleteById(salesBillEntity.getId());
                    if (delete != 1) {
                        log.error(FoodTableConstants.FoodTableEnum.DELETE_SALES_FAIL.getMsg());
                        return Result.fail(FoodTableConstants.FoodTableEnum.DELETE_SALES_FAIL);
                    }
                }
            }
        }
        return Result.ok(FoodTableConstants.FoodTableEnum.DELETE_SUCCESS);
    }

}